<?php

//  $Id$
//  $HeadURL$

/**
 * 此类用于 后端事件处理
 * 一般的类只返回单纯的结果，额外结果由这里处理，如做某件事成功与否返回  true /false
 * Fire和 Add的不同， Fire 表示直接处理事件， Add 把事件收集起来最后再处理。
 * 总包装层再进一步把 事件倒到前台。
 */
class DnEvent {
	public $events = array ();
	public $is_inited = false;
	public $is_simplemode = true;
	/**
	 * 单例模式
	 * @param $obj 用于替代默认对象;
	 */
	public static function Self($obj = null) {
		return DnMisc :: SingletonSelf($obj, __CLASS__);
	}
	public function __construct() {
	}
	public function dispatchEvents() {
		if (!$this->is_simplemode) {
			return $this->events;
		}
		$ret = array ();
		foreach ($this->events as $event) {
			$ret = $ret + $event;
		}
		return $ret;
	}
	public function addEvent($eventname, $args = array ()) {
		if(!is_string($eventname)){
			_log("error EventName!");
			return;
		}
		$this->events[]=array($eventname=>$args);
	}
	public function init() {
		$this->is_inited = true;
		//对 Dnservices 来说，直接处理事件，不保留结果
		//对单一模块来说，处理事件后保存在session 里

	}
	public function fireEvent($eventname, $args = array ()) {
		$ret=null;
		$methodname = 'on' . $eventname;
		if (!method_exists($this, $methodname)) {
			return array ();
		}
		if(!is_array($args)){
			_log(get_class($args));
		}
		//try {
			$ret = call_user_func_array(array (
				& $this,
				$methodname
			), $args);
		//} catch (Exception $ex) {
			//$ret = array ();
		//} /*finally {
			//_log($ret);
		//}
		return $ret;
	}
	public function onError($ex) {
		if (!is_a($ex, 'DnException') && is_a($ex, 'Exception')) {
			throw $ex;
		}
		$this->addEvent($ex->error_id, $ex->params);
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static function Add($eventname, $args = array ()) {
		return self :: Self()->addEvent($eventname, $args);
	}
	public static function Fire($eventname, $args = array ()) {
		if(!is_array($args)){
		}
		return self :: Self()->fireEvent($eventname, $args);
	}
	public static function Dispatch() {
		return self :: Self()->dispatchEvents();
	}
	public static function AddOn($condition,$eventname,$args)
	{
		if($condition){
			DnEvent::Add($eventname,$args);
		}
	}
}